import express from 'express';
import cors from 'cors';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import http from 'http';
import https from 'https';
import { Server } from 'socket.io';

import routes, { setupRoutes } from './routes/index.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const app = express();
const server = http.createServer(app);
const PORT = 3001;

// 创建Socket.IO实例
const io = new Server(server, {
  cors: {
    origin: '*',
    methods: ['GET', 'POST', 'PUT', 'DELETE'],
    credentials: true
  }
});

// 保存Socket.IO实例到app对象，便于其他模块访问
app.set('io', io);

// 中间件
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 静态文件服务
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));

// 确保上传目录存在
const uploadDirs = [
  path.join(__dirname, 'uploads', 'temp'),
  path.join(__dirname, 'uploads', 'avatars')
];

uploadDirs.forEach(dir => {
  if (!fs.existsSync(dir)) {
    fs.mkdirSync(dir, { recursive: true });
  }
});

// 添加路由调试日志（在路由之前）
app.use('/api', (req, res, next) => {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.originalUrl}`);
  next();
});

// API路由
// 调用setupRoutes初始化所有路由，传入app实例以便设置Socket.IO连接
setupRoutes(app);
app.use('/api', routes);
console.log('API路由已注册，包括 /api/permissions');

// 存储房间信息
const rooms = new Map(); // roomId -> { users: Map(userId -> userData), hostId: string, maxParticipants: number, createdAt: Date }
const MAX_PARTICIPANTS = 8; // 最大参与者数量

// WebSocket连接处理
io.on('connection', (socket) => {
  console.log('新的客户端连接:', socket.id);

  // 加入房间
  socket.on('join-room', ({ roomId, userId, userName, isHost = false }) => {
    console.log(`🚪 用户 ${userName} (${userId}) 加入房间 ${roomId}, 是否主持人: ${isHost}`);
    console.log(`   房间ID长度: ${roomId?.length}, 类型: ${typeof roomId}`);

    if (!roomId || typeof roomId !== 'string') {
      console.error('❌ 无效的房间ID:', roomId);
      socket.emit('room-error', {
        type: 'room-not-found',
        message: '房间ID无效'
      });
      return;
    }

    // 初始化房间信息
    if (!rooms.has(roomId)) {
      // 如果是新房间，初始化房间信息
      rooms.set(roomId, {
        users: new Map(),
        hostId: isHost ? userId : null,
        maxParticipants: MAX_PARTICIPANTS,
        createdAt: new Date()
      });
    }

    const room = rooms.get(roomId);

    // 检查房间是否已满
    if (room.users.size >= room.maxParticipants) {
      console.log(`❌ 房间 ${roomId} 已满 (${room.users.size}/${room.maxParticipants})`);
      socket.emit('room-error', {
        type: 'room-full',
        message: `房间已满，最多支持 ${room.maxParticipants} 人`
      });
      return;
    }

    // 如果房间没有主持人且这是第一个用户，设为主持人
    if (!room.hostId && room.users.size === 0) {
      room.hostId = userId;
      isHost = true;
    }

    // 检查是否已存在该用户
    if (room.users.has(userId)) {
      console.log(`⚠️ 用户 ${userId} 已存在于房间 ${roomId}`);
      // 更新现有用户的 socketId
      room.users.get(userId).socketId = socket.id;
    }

    socket.join(roomId);

    // 添加用户到房间
    room.users.set(userId, {
      id: userId,
      name: userName,
      socketId: socket.id,
      isVideoOn: true,
      isAudioOn: true,
      isScreenSharing: false,
      isHost: userId === room.hostId
    });

    // 获取所有用户列表
    const users = Array.from(room.users.values()).map(user => ({
      id: user.id,
      name: user.name,
      isVideoOn: user.isVideoOn,
      isAudioOn: user.isAudioOn,
      isScreenSharing: user.isScreenSharing,
      isHost: user.isHost
    }));

    console.log(`✅ 用户 ${userName} 成功加入房间 ${roomId}, 当前人数: ${users.length}/${room.maxParticipants}`);

    // 通知房间内其他用户有新用户加入
    socket.to(roomId).emit('user-joined', { userId, userName, users });

    // 向新加入的用户发送当前用户列表
    socket.emit('user-joined', { userId, userName, users });
  });

  // 转发 WebRTC offer
  socket.on('offer', ({ roomId, to, offer }) => {
    const room = rooms.get(roomId);
    if (!room) {
      console.log('⚠️ 房间不存在:', roomId);
      return;
    }

    // 找到发送者和接收者的 userId
    let targetSocket = null;
    let senderUserId = null;

    room.users.forEach((user, userId) => {
      if (user.socketId === socket.id) {
        senderUserId = userId;
      }
      if (userId === to) {
        targetSocket = io.sockets.sockets.get(user.socketId);
      }
    });

    if (targetSocket && senderUserId) {
      console.log(`📤 转发 offer: ${senderUserId} -> ${to} (房间: ${roomId})`);
      targetSocket.emit('offer', { from: senderUserId, offer });
    } else {
      console.log('⚠️ 无法找到目标用户或发送者:', { roomId, to, senderUserId, targetSocket: !!targetSocket });
    }
  });

  // 转发 WebRTC answer
  socket.on('answer', ({ roomId, to, answer }) => {
    const room = rooms.get(roomId);
    if (!room) {
      console.log('⚠️ 房间不存在:', roomId);
      return;
    }

    // 找到发送者和接收者的 userId
    let targetSocket = null;
    let senderUserId = null;

    room.users.forEach((user, userId) => {
      if (user.socketId === socket.id) {
        senderUserId = userId;
      }
      if (userId === to) {
        targetSocket = io.sockets.sockets.get(user.socketId);
      }
    });

    if (targetSocket && senderUserId) {
      console.log(`📤 转发 answer: ${senderUserId} -> ${to} (房间: ${roomId})`);
      targetSocket.emit('answer', { from: senderUserId, answer });
    } else {
      console.log('⚠️ 无法找到目标用户或发送者:', { roomId, to, senderUserId, targetSocket: !!targetSocket });
    }
  });

  // 转发 ICE candidate
  socket.on('ice-candidate', ({ roomId, to, candidate }) => {
    const room = rooms.get(roomId);
    if (!room) {
      console.log('⚠️ 房间不存在:', roomId);
      return;
    }

    // 找到发送者和接收者的 userId
    let targetSocket = null;
    let senderUserId = null;

    room.users.forEach((user, userId) => {
      if (user.socketId === socket.id) {
        senderUserId = userId;
      }
      if (userId === to) {
        targetSocket = io.sockets.sockets.get(user.socketId);
      }
    });

    if (targetSocket && senderUserId) {
      targetSocket.emit('ice-candidate', { from: senderUserId, candidate });
    } else {
      console.log('⚠️ 无法找到目标用户或发送者:', { roomId, to, senderUserId, targetSocket: !!targetSocket });
    }
  });

  // 媒体状态变化
  socket.on('media-state-change', ({ roomId, userId, isVideoOn, isAudioOn }) => {
    const room = rooms.get(roomId);
    if (room && room.users.has(userId)) {
      const user = room.users.get(userId);
      if (isVideoOn !== undefined) user.isVideoOn = isVideoOn;
      if (isAudioOn !== undefined) user.isAudioOn = isAudioOn;

      // 广播给房间内所有其他用户
      socket.to(roomId).emit('media-state-change', { userId, isVideoOn, isAudioOn });
    }
  });

  // 屏幕共享状态变化
  socket.on('screen-share-state', ({ roomId, userId, isScreenSharing }) => {
    const room = rooms.get(roomId);
    if (room && room.users.has(userId)) {
      const user = room.users.get(userId);
      user.isScreenSharing = isScreenSharing;

      // 广播给房间内所有其他用户
      socket.to(roomId).emit('screen-share-state', { userId, isScreenSharing });
    }
  });

  // 聊天消息
  socket.on('chat-message', ({ roomId, message }) => {
    // 广播给房间内所有其他用户
    socket.to(roomId).emit('chat-message', { message });
  });

  // 离开房间
  socket.on('leave-room', ({ roomId, userId }) => {
    console.log(`用户 ${userId} 离开房间 ${roomId}`);

    const room = rooms.get(roomId);
    if (room) {
      room.users.delete(userId);

      // 获取剩余用户列表
      const users = Array.from(room.users.values()).map(user => ({
        id: user.id,
        name: user.name,
        isVideoOn: user.isVideoOn,
        isAudioOn: user.isAudioOn,
        isScreenSharing: user.isScreenSharing
      }));

      // 通知房间内其他用户
      socket.to(roomId).emit('user-left', { userId, users });

      // 如果房间为空，删除房间
      if (room.users.size === 0) {
        rooms.delete(roomId);
        console.log(`房间 ${roomId} 已清空并删除`);
      }
    }

    socket.leave(roomId);
  });

  // 监听客户端断开连接
  socket.on('disconnect', () => {
    console.log('客户端断开连接:', socket.id);

    // 从所有房间中移除该用户
    rooms.forEach((room, roomId) => {
      room.users.forEach((user, userId) => {
        if (user.socketId === socket.id) {
          room.users.delete(userId);

          // 获取剩余用户列表
          const users = Array.from(room.users.values()).map(u => ({
            id: u.id,
            name: u.name,
            isVideoOn: u.isVideoOn,
            isAudioOn: u.isAudioOn,
            isScreenSharing: u.isScreenSharing
          }));

          // 通知房间内其他用户
          io.to(roomId).emit('user-left', { userId, users });

          // 如果房间为空，删除房间
          if (room.users.size === 0) {
            rooms.delete(roomId);
            console.log(`房间 ${roomId} 已清空并删除`);
          }
        }
      });
    });
  });
});

// 错误处理中间件
app.use((err, req, res, next) => {
  console.error('服务器错误:', err);
  res.status(500).json({
    error: '服务器内部错误',
    message: err.message
  });
});

// 404处理
app.use('*', (req, res) => {
  res.status(404).json({
    error: '接口不存在',
    path: req.originalUrl
  });
});

// 启动服务器
server.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`);
  console.log('WebSocket服务已启动');
  console.log('MVC架构重构完成');
  console.log('数据目录:', path.join(__dirname, 'data'));
});

// 导出app和io，便于测试和其他模块使用
export { app, io };